package pers.cz.redis;

import pers.cz.spring.SpringContextUtil;
import io.netty.bootstrap.Bootstrap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * redis配置类
 * @program: PostGirl-panent
 * @description: RedisConfig
 * @author: Cheng Zhi
 * @create: 2021-07-03 14:01
 **/
@Configuration
@ConfigurationProperties(prefix = "redis")
public class RedisConfig {

    Logger log = LoggerFactory.getLogger(RedisConfig.class);

    // ip
    private String host ;

    private Integer port ;

    private String password ;

    // 最大激活连接数
    private Long maxActive ;

    // 最大连接等待时间
    private Long maxWait ;

    // 最大连接等待中的数量
    private Integer maxIdle ;

    private Integer minIdle ;

    // 超时时间
    private Integer timeout ;

    // 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时
    private Boolean blockWhenExhausted;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Long getMaxActive() {
        return maxActive;
    }

    public void setMaxActive(Long maxActive) {
        this.maxActive = maxActive;
    }

    public Long getMaxWait() {
        return maxWait;
    }

    public void setMaxWait(Long maxWait) {
        this.maxWait = maxWait;
    }

    public Integer getMaxIdle() {
        return maxIdle;
    }

    public void setMaxIdle(Integer maxIdle) {
        this.maxIdle = maxIdle;
    }

    public Integer getMinIdle() {
        return minIdle;
    }

    public void setMinIdle(Integer minIdle) {
        this.minIdle = minIdle;
    }

    public Integer getTimeout() {
        return timeout;
    }

    public void setTimeout(Integer timeout) {
        this.timeout = timeout;
    }

    public Boolean getBlockWhenExhausted() {
        return blockWhenExhausted;
    }

    public void setBlockWhenExhausted(Boolean blockWhenExhausted) {
        this.blockWhenExhausted = blockWhenExhausted;
    }

    @Bean
    public JedisPool redisPoolFactory() {

        log.info("JedisPool注入成功！！");
        log.info("redis地址：" + host + ":" + port);
        log.info("开始心跳检测（redis）");

        Bootstrap bootstrap = new Bootstrap();
        ClientStarter clientStarter = new ClientStarter(bootstrap,host,port);
        clientStarter.connect();
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWait);
        jedisPoolConfig.setMaxTotal(Integer.valueOf(maxActive + ""));
        // 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
        jedisPoolConfig.setBlockWhenExhausted(blockWhenExhausted);
        // 是否启用pool的jmx管理功能, 默认true
        jedisPoolConfig.setJmxEnabled(true);
        // Idle(空闲)时进行连接扫描
        jedisPoolConfig.setTestWhileIdle(true);
        // 表示idle object evitor两次扫描之间要sleep的毫秒数
        jedisPoolConfig.setTimeBetweenEvictionRunsMillis(30000);
        // 表示idle object evitor每次扫描的最多的对象数
        jedisPoolConfig.setNumTestsPerEvictionRun(10);
        // 表示一个对象至少停留在idle状态的最短时间，然后才能被idle object evitor扫描并驱逐；这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
        jedisPoolConfig.setMinEvictableIdleTimeMillis(60000);
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
        return jedisPool;

    }

    /**
     * 用于网络断开重连后重新获取redis连接，该方法给心跳检测类调用
     * @return
     */
    public JedisPool redisPoolFactoryGeneral() {

        RedisConfig bean = SpringContextUtil.getBean(RedisConfig.class);
        host = bean.getHost();
        port = bean.getPort();
        maxIdle = bean.getMaxIdle();
        maxWait = bean.getMaxWait();
        blockWhenExhausted = bean.getBlockWhenExhausted();
        password = bean.getPassword();
        timeout = bean.getTimeout();

        log.info("JedisPool注入成功！！");
        log.info("redis地址：" + host + ":" + port);
        log.info("开始心跳检测（redis）");

        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWait);
        // 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
        jedisPoolConfig.setBlockWhenExhausted(blockWhenExhausted);
        // 是否启用pool的jmx管理功能, 默认true
        jedisPoolConfig.setJmxEnabled(true);
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
        Jedis resource = jedisPool.getResource();
        return jedisPool;
    }

    /**
     * 获取一个redis连接
     * @return
     */
    public static Jedis getJedisResource() {
        JedisPool bean = SpringContextUtil.getBean(JedisPool.class);
        Jedis resource = bean.getResource();
        return resource;
    }
}
